<?php

namespace app\store\model;

use app\common\enum\order\PayStatus as PayStatusEnum;
use app\common\enum\order\Status as OrderStatusEnum;
use app\common\library\helper;
use app\common\model\CourseOrder;
use app\common\model\Store as StoreModel;
use think\Db;

/**
 * 商城模型
 * Class Store
 * @package app\store\model
 */
class Store extends StoreModel
{
    /* @var Goods $GoodsModel */
    private $GoodsModel;

    /* @var Order $GoodsModel */
    private $OrderModel;

    /* @var User $GoodsModel */
    private $UserModel;

    /**
     * @var CourseOrder $CourseOrder
     */
    private $CourseOrder;

    /**
     * 构造方法
     */
    public function initialize()
    {
        parent::initialize();
        /* 初始化模型 */
        $this->GoodsModel = new Goods;
        $this->OrderModel = new Order;
        $this->UserModel = new User;
        $this->CourseOrder = new CourseOrder();
    }

    /**
     * 后台首页数据
     * @return array
     * @throws \think\Exception
     */
    public function getHomeData()
    {
        $today = date('Y-m-d');
        $yesterday = date('Y-m-d', strtotime('-1 day'));
        // 最近七天日期
        $lately7days = $this->getLately7days();
        $data = [
            'widget-card' => [
                // 商品总量
                'goods_total' => $this->getGoodsTotal(),
                // 用户总量
                'user_total' => $this->getUserTotal(),
                // 订单总量
                'order_total' => $this->getOrderTotal(),
                // 评价总量
                //'comment_total' => $this->getCommentTotal()
                // 购买课程卡
                "user_buy" => $this->getBuyUser(),
                // 剩余上课次数
                "remain"=>$this->remain()
            ],
            'widget-outline' => [
                // 销售额(元)
                'order_total_price' => [
                    'tday' => bcadd($this->getOrderTotalPrice(), $this->getCourseOrderTotalPrice(), 2),
                    'ytd' => bcadd($this->getOrderTotalPrice($yesterday), $this->getCourseOrderTotalPrice($yesterday), 2),
                ],
                // 支付订单数
                'order_total' => [
                    'tday' => bcadd($this->getOrderTotal(), $this->getCourseOrderTotal(), 0),
                    'ytd' => bcadd($this->getOrderTotal($yesterday), $this->getCourseOrderTotal($yesterday), 0),
                ],
                // 新增用户数
                'new_user_total' => [
                    'tday' => $this->getUserTotal($today),
                    'ytd' => $this->getUserTotal($yesterday)
                ],
                // 下单用户数
                'order_user_total' => [
                    'tday' => $this->getPayOrderUserTotal($today),
                    'ytd' => $this->getPayOrderUserTotal($yesterday)
                ],
                //私教
                "course1_total" => [
                    'tday' => $this->getCourse(null, 1),
                    'ytd' => $this->getCourse($yesterday, 1)
                ],
                //团课
                "course2_total" => [
                    'tday' => $this->getCourse(null, 2),
                    'ytd' => $this->getCourse($yesterday, 2)
                ],
                //私教 课时
                "course1_price_total" => [
                    'tday' => $this->getCoursePrice(null, 1),
                    'ytd' => $this->getCoursePrice($yesterday, 1)
                ],
                //私教 课时
                "course2_price_total" => [
                    'tday' => $this->getCoursePrice(null, 2),
                    'ytd' => $this->getCoursePrice($yesterday, 2)
                ],

            ],
            'widget-echarts' => [
                // 最近七天日期
                'date' => helper::jsonEncode($lately7days),
                'order_total' => helper::jsonEncode($this->getOrderTotalByDate($lately7days)),
                'order_total_price' => helper::jsonEncode($this->getOrderTotalPriceByDate($lately7days))
            ]
        ];

        return $data;
    }

    /**
     * 最近七天日期
     */
    private function getLately7days()
    {
        // 获取当前周几
        $date = [];
        for ($i = 0; $i < 7; $i++) {
            $date[] = date('Y-m-d', strtotime('-' . $i . ' days'));
        }
        return array_reverse($date);
    }

    /**
     * 获取商品总量
     * @return string
     * @throws \think\Exception
     */
    private function getGoodsTotal()
    {
        return number_format($this->GoodsModel->getGoodsTotal());
    }

    /**
     * 获取用户总量
     * @param null $day
     * @return string
     * @throws \think\Exception
     */
    private function getUserTotal($day = null)
    {
        return number_format($this->UserModel->getUserTotal($day));
    }

    /**
     * 获取订单总量
     * @param null $day
     * @return string
     * @throws \think\Exception
     */
    private function getOrderTotal($day = null)
    {
        return number_format($this->OrderModel->getPayOrderTotal($day, $day));
    }

    private function getCourseOrderTotal($day = null)
    {
        return number_format($this->CourseOrder->getPayOrderTotal($day, $day));
    }

    /**
     * 获取订单总量 (指定日期)
     * @param $days
     * @return array
     * @throws \think\Exception
     */
    private function getOrderTotalByDate($days)
    {
        $data = [];
        foreach ($days as $day) {
            $data[] = bcadd($this->getOrderTotal($day), $this->getCourseOrderTotal($day));
        }
        return $data;
    }

    /**
     * 获取评价总量
     * @return string
     */
    private function getCommentTotal()
    {
        $model = new Comment;
        return number_format($model->getCommentTotal());
    }

    /**
     * 获取某天的总销售额
     * @param null $day
     * @return string
     */
    public function getOrderTotalPrice($day = null)
    {
        return helper::number2($this->OrderModel->getOrderTotalPrice($day, $day));
    }

    public function getCourseOrderTotalPrice($day = null)
    {
        return helper::number2($this->CourseOrder->getOrderTotalPrice($day, $day));
    }

    /**
     * 某个期间总销售额
     * @param $startDate
     * @param $endDate
     * @return string
     */
    public function getTotal($startDate, $endDate)
    {
        return $this->getCourseOrderTotalPrice1($startDate, $endDate);
        return bcadd($this->getOrderTotalPrice1($startDate, $endDate), $this->getCourseOrderTotalPrice1($startDate, $endDate), 2);
    }

    private function getOrderTotalPrice1($startDate = null, $endDate = null)
    {
        return helper::number2($this->OrderModel->getOrderTotalPrice($startDate, $endDate));
    }

    private function getCourseOrderTotalPrice1($startDate = null, $endDate = null)
    {
        return helper::number2($this->CourseOrder->getOrderTotalPrice($startDate, $endDate));
    }

    /**
     * 获取订单总量 (指定日期)
     * @param $days
     * @return array
     */
    private function getOrderTotalPriceByDate($days)
    {
        $data = [];
        foreach ($days as $day) {
            $data[] = bcadd($this->getOrderTotalPrice($day), $this->getCourseOrderTotalPrice($day), 2);
        }
        return $data;
    }

    /**
     * 获取某天的下单用户数
     * @param $day
     * @return float|int
     */
    private function getPayOrderUserTotal($day)
    {
        return number_format($this->OrderModel->getPayOrderUserTotal($day));
    }

    /**
     * 会员数量
     * @return string
     * @throws \think\Exception
     */
    public function getBuyUser($startDate = null, $endDate = null)
    {
        $filter = [
            'pay_status' => PayStatusEnum::SUCCESS,
            'order_status' => ['<>', OrderStatusEnum::CANCELLED],
            'is_delete' => 0
        ];
        if (!is_null($startDate) && !is_null($endDate)) {
            $filter['pay_time'] = [
                ['>=', strtotime($startDate)],
                ['<', strtotime($endDate) + 86400],
            ];
        }

        return number_format($this->CourseOrder->distinct(true)->field('user_id')->where($filter)->count());
    }
    

    private function getCourse($day, $type)
    {
        return $this->getCourseTotal($day, $day, $type);
    }

    private function getCourseTotal($startDate = null, $endDate = null, $type = '')
    {
        $sql = "select count(r.id) as num 
from yoshop_course_reservation as r
         left join yoshop_course_order yco on r.course_order_id = yco.order_id
         left join yoshop_course_order_detail ycod on r.course_order_id = ycod.course_order_id
where yco.pay_status = 20
  and yco.is_delete = 0 and r.status=2 and r.wxapp_id=" . self::$wxapp_id;
        if (!is_null($startDate) && !is_null($endDate)) {
            $sql .= " and r.date>='{$startDate}'";
            $sql .= " and r.date<='{$endDate}'" ;
        }
        if ($type) {
            $sql .= " and ycod.type={$type}";
        }
        $result = Db::query($sql);
        return $result['0']['num'];
    }

    private function getCoursePrice($day, $type)
    {
        return $this->getCoursePriceTotal($day, $day, $type);
    }

    private function getCoursePriceTotal($startDate = null, $endDate = null, $type = '')
    {
        $sql = "select ycod.nums,
       ycod.total_price 
from yoshop_course_reservation as r
         left join yoshop_course_order yco on r.course_order_id = yco.order_id
         left join yoshop_course_order_detail ycod on r.course_order_id = ycod.course_order_id
where yco.pay_status = 20
  and yco.is_delete = 0 and r.status=2 and r.wxapp_id=" . self::$wxapp_id;
        if (!is_null($startDate) && !is_null($endDate)) {
            $sql .= " and r.date>='{$startDate}'";
            $sql .= " and r.date<='{$endDate}'" ;
        }
        if ($type) {
            $sql .= " and ycod.type={$type}";
        }
        $result = Db::query($sql);
        $total_price = '0';
        foreach ($result as $value) {
            $price = bcdiv($value['total_price'], $value['nums'], 2);
            $total_price = bcadd($price, $total_price, 2);
        }
        return $total_price;
    }
    
    public function remain(){
        $sql="SELECT sum(ycod.`remain_nums`) as remain_nums ,SUM(`nums`) as nums FROM `yoshop_course_order_detail` ycod LEFT JOIN `yoshop_course_order` yco ON yco.`order_id`=ycod.`course_order_id` WHERE yco.`pay_status`=20 and yco.`is_delete`=0 AND yco.order_status IN (10,30) and yco.wxapp_id=" . self::$wxapp_id;
        $result = Db::query($sql);
        return $result[0];
    }
}